package com.zpark;

import java.util.Scanner;

public class TurnOffLights {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入您要测试的案例数");
        int cases = scan.nextInt();
        // 直接让用户在每个案例中输入(1、1)~(5、6)的所有30盏灯的状态
        for(int i = 0; i < cases; i++){
            // 用双层for嵌套，让用户给30盏灯赋予初值
            for(int r = 1; r < 6; r++){
                System.out.println("请输入第" + r + "行的6盏灯");
                String str = scan.next();
                for(int c = 1; c < 7; c++){
                    char cha = str.charAt(c - 1);
                    puzzle[r][c] = Integer.parseInt(String.valueOf(cha));
                }
            }
            // 枚举第一行6个开关的状态，看看能不能熄灭这种状态的30盏灯
            enumerate();
            System.out.println("PUZZLE #" + (i + 1));
            // 输出能够熄灭30盏灯的30个开关的状态
            for(int r = 1; r < 6; r++){
                for(int c = 1; c < 7; c++)
                    System.out.printf("%d ", press[r][c]);
                System.out.println();
            }
        }
    }
    /* 表示灯的二维数组，灯有两种状态：0-灭；1-亮。 */
    static int[][] puzzle = new int[6][8];
    /* 表示按钮的二维数组， 按钮有两种状态：0-不需要按；1-需要被按下*/
    static int[][] press = new int[6][8];

    /**
     * 枚举第一行开关的状态
     *  如果开关的某一种状态不能熄灭所有的灯，则继续枚举开关的下一状态
     */
    private static void enumerate(){
        int c;  // 声明一个变量c，用于描述列
        for(c = 1; c < 7; c++)  // 将列范围定在1-6
            press[1][c] = 0;    // 将第一行的6个开关都置为不按下的状态
        // 开始枚举（如果第一行开关的状态不能熄灭所有的灯，那就将第一行开关切换到下一个状态）
        while(!guess()){    // 猜测当前第一行开关能不能熄灭所有的灯
            press[1][1]++;  // 让第一个开关的状态自增1
            c = 1;  // 将列初始化为1
            while(press[1][c] > 1){  //  1,c 位置的开关如果状态大于1
                press[1][c] = 0;  // 就将该位置的开关置为0
                c++;  // 将列变为下一个值
                press[1][c]++;  //
                if(c == 7) // 如果超过了第六列
                    break;  // 跳出
            }
        }
    }
    /**
     * 判断第一行开关是否能熄灭所有的灯
     * @return 如果返回true，表示可以熄灭所有的灯，否则，不能。
     */
    private static boolean guess(){
        /*
         * 根据press第1行和puzzle数组，计算press各行的值
         */
        for(int r = 1; r < 5; r++){
            for(int c = 1; c < 7; c++){
                press[r + 1][c] = (puzzle[r][c] + press[r - 1][c] + press[r][c - 1] + press[r][c + 1] + press[r][c]) % 2;
            }
        }
        /*
         * 判断所计算的press数组第五行(press[5])能否熄灭第5行的所有灯
         */
        for(int c = 1; c < 7; c++){
            if(puzzle[5][c] != (press[4][c] + press[5][c - 1] + press[5][c + 1] + press[5][c]) % 2)
                return false;
        }
        return true;
    }

}
